package tools;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CodingErrorAction;

import org.mozilla.universalchardet.UniversalDetector;

public class CharsetConverter {

	public static String CharsetConverterEUCKR2UTF8(String srcFP) {
		return convertCharset(srcFP, "EUC-KR", "UTF-8");
	}

	public static String CharsetConverterUTF82EUCKR(String srcFP) {
		return convertCharset(srcFP, "UTF-8", "EUC-KR");
	}

	/**
	 * Convert String to (Encoded) String
	 * 
	 * CHARSET EUC-KR, UTF-8
	 * 
	 * @param srcFP
	 *            : File Path
	 * @param charsetIN
	 *            : INPUT FILE CHARSET
	 * @param charsetOUT
	 *            : OUTPUT FILE CHARSET
	 * @return String outputFP
	 */
	private static String convertCharset(String srcFP, String charsetIN, String charsetOUT) {

		if (srcFP.length() == 0) {
			System.err.println("Input Filename...");

		}

		String outputFP = srcFP + ".converted";

		try {
			BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(srcFP), charsetIN));

			BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputFP), charsetOUT));

			String s;

			while ((s = in.readLine()) != null) {
				out.write(s);
				out.newLine();
			}
			in.close();
			out.close();
		} catch (IOException e) {
			System.err.println(e);
		}
		return outputFP;

	}

	/**
	 * READ a file based on character set
	 * 
	 * @param srcFP
	 * @param charsetIN
	 * @return content - Sting based on the given charset
	 */
	public static String readTextFile(String srcFP, String charsetIN) {
		String content = "";

		try {
			BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(srcFP), charsetIN));

			String line = "";

			while ((line = in.readLine()) != null) {
				content = content + line;
			}
			in.close();

		} catch (Exception e) {
			System.err.println("Error: " + e.getMessage());
		}
		return content;
	}

	/**
	 * Write a file based on character set DELETE, if the target file exists
	 * 
	 * @param filePath
	 *            : File
	 * @param charsetOut
	 * @return content - Sting based on the given charset
	 */
	public static boolean writeTextFile(String destFP, String content, String charsetOut) {

		boolean result = false;

		File destFile = new File(destFP);
		if (destFile.exists()) {
			destFile.delete();
			destFile = null;
		}
		try {
			FileOutputStream fos = new FileOutputStream(destFP);
			OutputStreamWriter osw = new OutputStreamWriter(fos, charsetOut);
			BufferedWriter out = new BufferedWriter(osw);
			out.write(content);

			out.close();
			osw.close();
			fos.close();

			result = true;
		} catch (IOException e) {
			System.err.println(e);
		}
		return result;
	}

	/**
	 * 
	 * Convert String to (Encoded) String
	 * 
	 * @param inString
	 *            -
	 * @return Encoded String
	 * 
	 */
	public String filterNonAscii(String inString) {
		// Create the encoder and decoder for the character encoding
		Charset charset = Charset.forName("US-ASCII");
		CharsetDecoder decoder = charset.newDecoder();
		CharsetEncoder encoder = charset.newEncoder();
		// This line is the key to removing "unmappable" characters.
		encoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
		String result = inString;

		try {
			// Convert a string to bytes in a ByteBuffer
			ByteBuffer bbuf = encoder.encode(CharBuffer.wrap(inString));

			// Convert bytes in a ByteBuffer to a character ByteBuffer and then
			// to a string.
			CharBuffer cbuf = decoder.decode(bbuf);
			result = cbuf.toString();
		} catch (CharacterCodingException cce) {
		}

		return result;
	}

	/**
	 * @param FilePath
	 * @return String - EUC-KR, UTF8, FAILED
	 */

	public static String detectTextEncoding(String filePath) {

		byte[] buf = new byte[4096];

		UniversalDetector detector = new UniversalDetector(null);

		try {
			java.io.FileInputStream fis;
			fis = new java.io.FileInputStream(filePath);

			int nread;

			try {
				while ((nread = fis.read(buf)) > 0 && !detector.isDone()) {
					detector.handleData(buf, 0, nread);
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			detector.dataEnd();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		String encoding = detector.getDetectedCharset();
		if (encoding != null) {
			return encoding;
		} else {
			return "FAILED";
		}
	}
}